<?php

    #-------------------------------------------------------------#
	# This file is part of the Tekuna MVC Microframework for PHP. #
	# (c) 2009 Niels Jäckel <niels.jaeckel@tekuna.org>            #
	# Please visit http://tekuna.org/ for more information.       #
	#                                                             #
	# This software is licensed under the MIT License. Please     #
	# view the LICENSE file for the full text of this license.    #
    #-------------------------------------------------------------#


	Tekuna :: load('org.tekuna.core.config.TekunaConfigurationElement');
	Tekuna :: load('org.tekuna.core.config.ApplicationComponentRoute');
	Tekuna :: load('org.tekuna.core.config.InvalidConfigurationException');


	/**
	 * This class represents a configured component in the application.xml
	 * configuration file of Tekuna. Each component has a slot, and
	 *
	 *   - a fragment OR
	 *   - a controller OR
	 *   - several routes, each pointing to
	 *     - a fragment OR
	 *     - a controller
	 *
	 * The validation of these constraints is not part of this class. It is just
	 * an information provider for easy representation of the configuration file.
	 */

	class ApplicationComponent implements TekunaConfigurationElement {

		protected
			$sSlot = NULL,
			$sFragment = NULL,
			$sController = NULL,
			$iStatus = NULL,
			$arrRoutes = array();


		/**
		 * Checks if this instance of a component is validly configured.
		 *
		 * @return boolean TRUE if valid
		 */

		public function isValid() {

			// the the sum of given fragment, controller and routes
			$iFeatureSum  = intval($this -> hasFragment());
			$iFeatureSum += intval($this -> hasController());
			$iFeatureSum += intval($this -> hasRoutes());

			return ($this -> sSlot !== NULL) && ($iFeatureSum === 1);
		}


		/**
		 * Set the slot value
		 *
		 * @param string $sSlot
		 */

		public function setSlot($sSlot) {

			$this -> sSlot = $sSlot;
		}


		/**
		 * @return string returns the slot value
		 */

		public function getSlot() {

			return $this -> sSlot;
		}


		/**
		 * Set the fragment. Implicitly the controller value and the routes
		 * are set to NULL.
		 *
		 * @param string $sFragment
		 */

		public function setFragment($sFragment) {

			$this -> sFragment = $sFragment;
		}


		/**
		 * @return string returns the fragment value
		 */

		public function getFragment() {

			return $this -> sFragment;
		}


		/**
		 * @return boolean returns TRUE, if the component holds a fragment
		 */

		public function hasFragment() {

			return ($this -> sFragment !== NULL);
		}


		/**
		 * Set the controller value. Implicitly the fragment value and the
		 * routes are set to NULL.
		 *
		 * @param string $sController
		 */

		public function setController($sController){

			$this -> sController = $sController;
		}


		/**
		 * @return string returns the controller value
		 */

		public function getController() {

			return $this -> sController;
		}


		/**
		 * @return boolean returns TRUE, if the component holds a controller
		 */

		public function hasController() {

			return ($this -> sController !== NULL);
		}


		/**
		 * Set a HTTP status
		 *
		 * @param integer $iStatus
		 */

		public function setStatus($iStatus) {

			$this -> iStatus = (integer) $iStatus;
		}


		/**
		 * @return integer the current status
		 */

		public function getStatus() {

			return $this -> iStatus;
		}


		/**
		 * Checks if a special status is set
		 *
		 * @return boolean status set or not
		 */

		public function hasStatus() {

			return ($this -> iStatus !== NULL);
		}


		/**
		 * Add new route object to the component. If the route's
		 * isValid() method fails, a InvalidConfigurationException
		 * is thrown.
		 *
		 * @param ApplicationComponentRoute $objRoute
		 */

		public function addRoute(ApplicationComponentRoute $objRoute) {

			if (! $objRoute -> isValid()) {

				throw new InvalidConfigurationException("The given route is not correctly configured.");
			}

			$this -> arrRoutes[] = $objRoute;
		}


		/**
		 * @return array returns an array with all defined routes
		 */

		public function getAllRoutes() {

			return $this -> arrRoutes;
		}


		/**
		 * @return boolean returns TRUE, if the component holds some routes
		 */

		public function hasRoutes() {

			return (count($this -> arrRoutes) > 0);
		}
	}
